package com.yklx.youke.service;

import com.yklx.youke.admin.mapper.PermissionMapper;
import com.yklx.youke.admin.mapper.UserRoleMapper;
import com.yklx.youke.entity.Admin;
import com.yklx.youke.entity.Parent;
import com.yklx.youke.entity.Teacher;
import com.yklx.youke.entity.User;
import com.yklx.youke.repository.UserRepository;
import com.yklx.youke.security.CustomUserDetails;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserService implements UserDetailsService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final UserRoleMapper userRoleMapper;
    private final PermissionMapper permissionMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder,
                       UserRoleMapper userRoleMapper, PermissionMapper permissionMapper, 
                       RedisTemplate<String, Object> redisTemplate) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.userRoleMapper = userRoleMapper;
        this.permissionMapper = permissionMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
        return new CustomUserDetails(user, permissionMapper);
    }

    public Optional<User> findById(UUID userId) {
        return userRepository.findById(userId);
    }

    public User findByUsername(String username) {
        return userRepository.findByUsername(username).orElse(null);
    }

    public User registerUser(String username, String email, String password, String roleId) {
        if (userRepository.existsByUsername(username)) {
            throw new RuntimeException("Username already exists: " + username);
        }

        if (userRepository.existsByEmail(email)) {
            throw new RuntimeException("Email already exists: " + email);
        }

        // 创建用户，不直接设置角色，而是通过user_roles表关联
        User user = new User();
        user.setUsername(username);
        user.setEmail(email);
        user.setPasswordHash(passwordEncoder.encode(password));

        User savedUser = userRepository.save(user);

        // 为用户分配角色
        if (roleId != null && !roleId.isEmpty()) {
            com.yklx.youke.entity.UserRole userRole = new com.yklx.youke.entity.UserRole(savedUser.getUserId().toString(), roleId);
            userRoleMapper.assignRoleToUser(userRole);
        }

        return savedUser;
    }

    public User save(User user) {
        return userRepository.save(user);
    }

    public List<User> findAll() {
        return userRepository.findAll();
    }
    
    /**
     * 将用户信息写入Redis缓存
     * @param username 用户名
     * @param userDetails 用户详细信息
     */
    public void cacheUserDetails(String username, UserDetails userDetails) {
        String key = "user_details:" + username;
        // 创建一个简化的用户信息映射，避免序列化复杂对象
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("username", userDetails.getUsername());
        userInfo.put("authorities", userDetails.getAuthorities().stream()
                           .map(authority -> authority.getAuthority())
                           .collect(Collectors.toList()));
        userInfo.put("enabled", userDetails.isEnabled());
        userInfo.put("accountNonExpired", userDetails.isAccountNonExpired());
        userInfo.put("credentialsNonExpired", userDetails.isCredentialsNonExpired());
        userInfo.put("accountNonLocked", userDetails.isAccountNonLocked());
        
        redisTemplate.opsForValue().set(key, userInfo);
    }
    
    /**
     * 从Redis获取用户信息
     * @param username 用户名
     * @return 用户详细信息
     */
    public Object getUserDetailsFromCache(String username) {
        String key = "user_details:" + username;
        return redisTemplate.opsForValue().get(key);
    }
    
    /**
     * 删除Redis中的用户信息缓存
     * @param username 用户名
     */
    public void removeUserDetailsFromCache(String username) {
        String key = "user_details:" + username;
        redisTemplate.delete(key);
    }
}